package com.site.utils;

import java.io.File;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Base64;
import java.util.UUID;

/**
 * 文件加密工具类
 */
public class FileNameUtil {
    /**
     * 对称加密 Base64  加密
     */
    public static String jdkBase64(String str){
        return Base64.getEncoder().encodeToString(str.getBytes());
    }

    /**
     * Base64 解密
     * @param str
     * @return
     */
    public static String deBase64(String str){
        return new String(Base64.getDecoder().decode(str.getBytes()));
    }

    /**
     * 非对称加密 MD5
     * @param str
     */
    public static String md5(String str){
        String md5Str = null;
        try {
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            md5.update(str.getBytes("UTF-8"));//处理字节数组
            md5Str = new String(md5.digest(),"UTF-8");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }finally {
            return md5Str;
        }
    }
    /**
     * @Method: makeFileName
     * @Description: 生成上传文件的文件名，文件名以：uuid+"_"+文件的原始名称
     * @param filename 文件的原始名称
     * @return uuid+"_"+文件的原始名称
     */
    public static String makeFileName(String filename){  //2.jpg    123123132asd_2.jpg
        //为防止文件覆盖的现象发生，要为上传文件产生一个唯一的文件名
        return UUID.randomUUID().toString() + "_" + filename;
    }

    /**
     * 为防止一个目录下面出现太多文件，要使用hash算法打散存储
     * @Method: makePath
     * @param filename 文件名，要根据文件名生成存储目录
     * @param savePath 文件存储路径
     * @return 新的存储目录
     */
    public static String makePath(String filename,String savePath){
        //得到文件名的hashCode的值，得到的就是filename这个字符串对象在内存中的地址
        int hashcode = filename.hashCode();
        int dir1 = hashcode&0xf;  //0--15
        int dir2 = (hashcode&0xf0)>>4;  //0-15
        //构造新的保存目录
        String dir = savePath + "\\" + dir1 + "\\" + dir2;  //upload\2\3  upload\3\5
        //File既可以代表文件也可以代表目录
        File file = new File(dir);
        //如果目录不存在
        if(!file.exists()){
            //创建目录
            file.mkdirs();
        }
        return dir;
    }

    /**
     * @Method: findFileSavePathByFileName
     * @Description: 通过文件名和存储上传文件根目录找出要下载的文件的所在路径
     * @param filename 要下载的文件名
     * @param saveRootPath 上传文件保存的根目录，也就是/WEB-INF/upload目录
     * @return 要下载的文件的存储目录
     */
    public static String findFileSavePathByFileName(String filename,String saveRootPath){
        int hashcode = filename.hashCode();
        int dir1 = hashcode&0xf;  //0--15
        int dir2 = (hashcode&0xf0)>>4;  //0-15
        String dir = saveRootPath + "\\" + dir1 + "\\" + dir2;  //upload\2\3  upload\3\5
        File file = new File(dir);
        if(!file.exists()){
            //创建目录
            file.mkdirs();
        }
        return dir;
    }

    public static void  main(String[] args){
        //Base64 加密
        System.out.println(jdkBase64("Hello"));
        System.out.println(jdkBase64("Hello"));
        //解密
        System.out.println(deBase64("SGVsbG8="));
        System.out.println(deBase64("SGVsbG8="));
        //MD5测试
        System.out.println(md5("Hello"));
        System.out.println(md5("Hello"));
        //UUID
        System.out.println(makeFileName("1.png"));
        System.out.println(makeFileName("1.png"));
        //通过文件名  创建文件夹
        String newFile = makeFileName("1.png");//文件名加密 保证唯一
        //文件夹创建多层，提高访问效率
        System.out.println("新文件存放地址："+makePath(newFile,"D:\\newIO"));
        System.out.println("读取："+findFileSavePathByFileName(newFile,"D:\\newIO"));

        System.out.println("读取："+findFileSavePathByFileName("6aba94bd-a7f5-4e58-a3a8-58c3d1edb162_文件错.png","D:\\newIO"));
    }
}
